package com.atguigu.userprofile.ml.train

import java.util.Properties

import com.atguigu.userprofile.common.util.MyPropertiesUtil
import com.atguigu.userprofile.ml.pipeline.MyPipeline
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object StudentGenderTrain {

  def main(args: Array[String]): Unit = {
    // 0 spark上下文环境
    val sparkConf: SparkConf = new SparkConf().setAppName("task_student_gender_train_app").setMaster("local[*]")
    val sparkSession: SparkSession = SparkSession.builder().config(sparkConf).enableHiveSupport().getOrCreate()


    // 1  提取数据

    val  sql=
      s"""
         | select uid ,
         |    case hair when '长发' then 10
         |              when  '短发' then 11
         |              when  '板寸' then 12 end hair ,
         |    height ,
         |    case skirt when '是' then  21
         |               when  '否' then 20 end skirt,
         |    case age when '80后' then 80
         |              when  '90后' then 90
         |              when  '00后' then 100 end age ,
         |    gender
         |    from  student
       """.stripMargin
    println(sql)
    sparkSession.sql("use user_profile2077");
    val dataFrame: DataFrame = sparkSession.sql(sql)

    // 2  拆分数据 训练数据和测试数据
    println("2 拆分数据 训练数据和测试数据")
    val  Array(trainDF,testDF) = dataFrame.randomSplit(Array(0.8,0.2))


    // 3  初始化流失线对象 参数
    println("3  初始化流失线对象 参数")
    val myPipeline: MyPipeline = new MyPipeline().setLabelColName("gender")
      .setFeatureColName(Array("hair", "height", "skirt", "age"))
      .setMaxCategories(20)
        .setMaxDepth(3)
        .setMinInstancesPerNode(10)
        .setMinInfoGain(0.01)
        .setMaxBins(20)
         .init()

    // 4  把训练数据 投入流水线 进行训练
    println("4  把训练数据 投入流水线 进行训练")
    myPipeline.train(trainDF)


    //  4.1 看看模型（决策树) 、  每个特征的权重(评分)
    println("4.1 看看模型（决策树)   每个特征的权重(评分)")
    myPipeline.printTree()
    myPipeline.printFeatureWeight()

    //(4,[0,1,2],[0.06144968765580544,0.6281516123505234,0.3103986999936712])
    //4 有四个特征
    //[0,1,2]  决策树 使用了哪个特征
    //[0.06144968765580544,0.6281516123505234,0.3103986999936712]  特征权重

    // 5  把测试数据 投入流水线模型 进行预测
    println("5  把测试数据 投入流水线模型 进行预测")
    val predictedDF: DataFrame = myPipeline.predict(testDF)
    predictedDF.show(1000,false)

    // 6  评估   准确率
    println("6  评估   准确率  、 精确率 、召回率")
    myPipeline.printEuvluateReport(predictedDF)
    //  7  模型储存
    val properties: Properties = MyPropertiesUtil.load("config.properties")
    val modelPath: String = properties.getProperty("model.student_gender.path")
    myPipeline.saveModel(modelPath)

  }

}
